package com.vrp3d.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vrp3d.common.enums.CommonEnum;
import com.vrp3d.common.enums.CommonExceptionEnum;
import com.vrp3d.common.exceptions.CommonException;
import com.vrp3d.common.utils.FileUtil;
import com.vrp3d.common.utils.ObjUtil;
import com.vrp3d.domain.dto.dist.DistForFrontDTO;
import com.vrp3d.domain.dto.news.*;
import com.vrp3d.domain.po.News;
import com.vrp3d.domain.po.NewsExample;
import com.vrp3d.mapper.NewsMapper;
import com.vrp3d.service.DistService;
import com.vrp3d.service.NewsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * 新闻
 *
 * @author vrp3d
 */
@Slf4j
@Service
public  class NewsServiceImpl extends AbsServiceImpl implements NewsService {

    @Autowired
    private DistService distService;

    @Autowired
    private NewsMapper newsMapper;

    private NewsExample.Criteria getCriteria(NewsExample example) {
        return example.createCriteria();
    }

    private NewsExample getExample() {
        return new NewsExample();
    }

    private News selectByPrimaryKey(Integer id) {
        NewsExample example = getExample();
        NewsExample.Criteria criteria = getCriteria(example);
        criteria.andStatusEqualTo(getNormalStatus());
        criteria.andIdEqualTo(id);
        List<News> list = newsMapper.selectByExampleWithBLOBs(example);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    public List<DistForFrontDTO> getTypeList() {
        return distService.findListByTypeContainsSubordinates(CommonEnum.NEWS_TYPE.getMsg());
    }

    @Override
    public Page<NewsListDTO> getNewsList(Page<NewsListDTO> page, NewsSearchDTO search) {
        List<NewsListDTO> list = newsMapper.getNewsList(page, search, getNormalStatus());
        return page.setRecords(list);
    }

    @Override
    public void whetherNewsHeadlinesAreAvailable(String title) {
        NewsExample example = getExample();
        NewsExample.Criteria criteria = getCriteria(example);
        criteria.andStatusEqualTo(getNormalStatus());
        title = title.trim();
        if (StringUtils.isBlank(title)) {
            throw new CommonException(CommonExceptionEnum.NEWS_TITLE_CANNOT_BE_EMPTY);
        }
        criteria.andTitleEqualTo(title);
        List<News> news = newsMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(news)) {
            throw new CommonException(CommonExceptionEnum.NEWS_TITLE_ALREADY_EXISTS);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void insertNews(NewsInsertDTO dto) {
        log.info("带新增新闻信息:{}", dto);

        // 检查名称是否可用
        String title = dto.getTitle().trim();
        whetherNewsHeadlinesAreAvailable(title);
        dto.setTitle(title);

        // 处理图片,验证图片后缀
        String picture = dto.getPicture();
        String pictureSuffix = CommonEnum.PICTURE_SUFFIX.getMsg();
        if (!pictureSuffix.contains(picture.substring(picture.lastIndexOf(CommonEnum.SEPARATOR_POINT.getMsg()) + 1).toLowerCase())) {
            throw new CommonException(CommonExceptionEnum.PICTURE_SUFFIX_DOES_NOT_MEET_SPECIFICATIONS);
        }
        // 判断文件是否存在
        if (!FileUtil.fileExists(picture)) {
            throw new CommonException(CommonExceptionEnum.FILE_DOES_NOT_EXIST);
        }

        // 移动图片
        String targetFilePath = CommonEnum.NEWS_FILE_DIRECTORY.getMsg() + getFileStoragePath();
        String s = FileUtil.moveFileToDirectory(picture, targetFilePath);
        dto.setPicture(s);

        // 插入数据库
        News newsInsert = new News();
        BeanUtils.copyProperties(dto, newsInsert);

        newsInsert.setStatus(getNormalStatus());
        Integer userId = getUser().getId();
        newsInsert.setCreateId(userId);
        newsInsert.setUpdateId(userId);

        Date date = getNowTime();
        newsInsert.setCreateTime(date);
        newsInsert.setUpdateTime(date);

        newsMapper.insertSelective(newsInsert);
    }

    @Override
    public void whetherNewsHeadlinesAreAvailableWhenUpdate(Integer id, String title) {
        NewsExample example = getExample();
        NewsExample.Criteria criteria = getCriteria(example);
        criteria.andStatusEqualTo(getNormalStatus());
        criteria.andIdEqualTo(id);
        title = title.trim();
        if (StringUtils.isBlank(title)) {
            throw new CommonException(CommonExceptionEnum.NEWS_TITLE_CANNOT_BE_EMPTY);
        }
        criteria.andTitleEqualTo(title);
        List<News> news = newsMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(news)) {
            throw new CommonException(CommonExceptionEnum.NEWS_TITLE_ALREADY_EXISTS);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateNews(NewsUpdateDTO dto) {
        log.info("待修改新闻信息:{}", dto);

        // 检查名称是否可用
        String title = dto.getTitle().trim();
        whetherNewsHeadlinesAreAvailable(title);
        dto.setTitle(title);

        // 新闻是否存在
        Integer id = dto.getId();
        News oldNews = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(oldNews)) {
            throw new CommonException(CommonExceptionEnum.NEWS_DOES_NOT_EXIST);
        }

        // 处理图片,验证图片后缀
        if (!oldNews.getPicture().equals(dto.getPicture())) {
            String picture = dto.getPicture();
            String pictureSuffix = CommonEnum.PICTURE_SUFFIX.getMsg();
            if (!pictureSuffix.contains(picture.substring(picture.lastIndexOf(CommonEnum.SEPARATOR_POINT.getMsg()) + 1).toLowerCase())) {
                throw new CommonException(CommonExceptionEnum.PICTURE_SUFFIX_DOES_NOT_MEET_SPECIFICATIONS);
            }
            // 判断文件是否存在
            if (!FileUtil.fileExists(picture)) {
                throw new CommonException(CommonExceptionEnum.FILE_DOES_NOT_EXIST);
            }

            // 移动图片
            String targetFilePath = CommonEnum.NEWS_FILE_DIRECTORY.getMsg() + getFileStoragePath();
            String s = FileUtil.moveFileToDirectory(picture, targetFilePath);
            dto.setPicture(s);

            // 删除旧的
            String deleteTargetFilePath = getDeleteStoragePath();
            FileUtil.deleteFile(oldNews.getPicture(), deleteTargetFilePath);
        }

        // 插入数据库
        News update = new News();
        BeanUtils.copyProperties(dto, update);

        Integer userId = getUser().getId();
        update.setUpdateId(userId);

        newsMapper.updateByPrimaryKeySelective(update);
    }

    @Override
    public NewsDTO selectById(Integer id) {
        News news = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(news)) {
            return null;
        } else {
            NewsDTO result = new NewsDTO();
            BeanUtils.copyProperties(news, result);
            return result;
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteNewsByIds(Integer id) {
        News news = selectByPrimaryKey(id);
        if (ObjUtil.isEmpty(news)) {
            throw new CommonException(CommonExceptionEnum.NEWS_DOES_NOT_EXIST);
        } else {
            // 处理图片
            String deleteTargetFilePath = getDeleteStoragePath();
            FileUtil.deleteFile(news.getPicture(), deleteTargetFilePath);

            News update = new News();
            update.setId(id);
            update.setStatus(getDeletedStatus());
            update.setDeleteId(getUser().getId());
            update.setDeleteTime(getNowTime());
            newsMapper.updateByPrimaryKeySelective(update);
        }
    }

}
